package com.hyt.it.ogt.ykcj.service.grade.impl;

import cn.hutool.core.io.IoUtil;
import com.hyt.it.ogt.ykcj.common.enums.BizErrorCode;
import com.hyt.it.ogt.ykcj.common.enums.CommonEnums;
import com.hyt.it.ogt.ykcj.common.exception.CustomException;
import com.hyt.it.ogt.ykcj.common.utils.DateUtils;
import com.hyt.it.ogt.ykcj.common.utils.IdUtils;
import com.hyt.it.ogt.ykcj.common.utils.SecurityUtils;
import com.hyt.it.ogt.ykcj.common.utils.bean.BeanUtils;
import com.hyt.it.ogt.ykcj.common.utils.poi.ExcelUtil;
import com.hyt.it.ogt.ykcj.domain.exam.ExamInfo;
import com.hyt.it.ogt.ykcj.domain.grade.EnterpriseExamineeInfo;
import com.hyt.it.ogt.ykcj.domain.grade.EnterpriseExamineeSubjectGrade;
import com.hyt.it.ogt.ykcj.domain.param.EnterpriseScoreLineSaveParam;
import com.hyt.it.ogt.ykcj.domain.param.ScoreLineItem;
import com.hyt.it.ogt.ykcj.domain.vo.EnterpriseExamineeInfoImportVo;
import com.hyt.it.ogt.ykcj.domain.vo.EnterpriseExamineeInfoVo;
import com.hyt.it.ogt.ykcj.domain.vo.EnterpriseExamineeSubjectGradeVo;
import com.hyt.it.ogt.ykcj.domain.vo.export.ExportEnterpriseExamineeStemScoreVo;
import com.hyt.it.ogt.ykcj.domain.vo.export.ExportEnterpriseExamineeSubjectGradeScoreVo;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.EnterpriseExamineeInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.EnterpriseExamineeSubjectGradeMapper;
import com.hyt.it.ogt.ykcj.service.exam.IEnterpriseExamScoreLineSettingService;
import com.hyt.it.ogt.ykcj.service.grade.IEnterpriseExamineeGradeImportService;
import com.hyt.it.ogt.ykcj.service.grade.IEnterpriseExamineeInfoService;
import com.hyt.it.ogt.ykcj.service.grade.IEnterpriseGroupExamineeInfoService;
import com.hyt.it.ogt.ykcj.service.grade.ImportAbstractService;
import com.hyt.it.ogt.ykcj.service.system.ISysDictDataService;
import com.hyt.loginfo.model.User;
import com.hyt.loginfo.service.IBaseLoginService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;

/**
 * 企业招聘考生成绩导入Service业务层处理
 *
 * @author liying
 * @date 2021-11-26
 */
@Service
public class EnterpriseExamineeGradeImportServiceImpl implements IEnterpriseExamineeGradeImportService {

    private static final Logger log = LoggerFactory.getLogger(EnterpriseExamineeGradeImportServiceImpl.class);


    @Autowired
    private ISysDictDataService dictDataService;

    @Resource(name = "threadPoolTaskExecutor")
    protected ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private IBaseLoginService iBaseLoginService;

    @Autowired
    private EnterpriseExamineeInfoMapper enterpriseExamineeInfoMapper;

    @Autowired
    private EnterpriseExamineeSubjectGradeMapper enterpriseExamineeSubjectGradeMapper;

    @Autowired
    private IEnterpriseExamineeInfoService enterpriseExamineeInfoService;

    @Autowired
    private IEnterpriseExamScoreLineSettingService enterpriseExamScoreLineSettingService;

    @Autowired
    private ExamInfoMapper examInfoMapper;

    @Autowired
    private IEnterpriseGroupExamineeInfoService enterpriseGroupExamineeInfoService;

    @Override
    public Object[] importtExcelFile(MultipartFile multipartFile, String examId, String subjectId) {
        log.info("导入成绩begin...文件类型为excel文件");
        long startTime = System.currentTimeMillis();
        FileInputStream fis = null;
        Workbook wb = null;
        try {
            String[] split = multipartFile.getOriginalFilename().split("\\.");  // . 特殊字符转义
            File file = null;
            String originalFilename = multipartFile.getOriginalFilename();
            String[] fileName = originalFilename.split("\\.");
            file = File.createTempFile(fileName[0], fileName[1]);
            multipartFile.transferTo(file);
            file.deleteOnExit();
            fis = new FileInputStream(file);
            if ( "xls".equals(split[1].toLowerCase())) {
                wb = new HSSFWorkbook(fis);
            } else if ("xlsx".equals(split[1].toLowerCase())) {
                wb = new XSSFWorkbook(fis);
            } else {
                throw new CustomException("文件类型错误");
            }
            // 开始解析
            Sheet sheet = wb.getSheetAt(0);     // 读取sheet 0
            int headRowIndex = sheet.getFirstRowNum();
            Row headRow = sheet.getRow(headRowIndex);
            if (null == headRow || sheet.getLastRowNum() <= 0) {
                throw new CustomException("导入文件无数据");
            }
            List<String> titles = new ArrayList<>(Arrays.asList(new String[] { "准考证号", "姓名", "性别", "证件号", "手机号码", "学历"}));
            List<String> keys = new ArrayList<>(Arrays.asList(new String[] { "admissionNo", "name", "sex", "idcard", "mobile", "education" }));
            int  fixedCellNum = 6; // 固定列数
            int firstCellIndex = headRow.getFirstCellNum(); // 开始列下标
            int lastCellIndex = headRow.getLastCellNum(); // 最后列下标
            List<ExportEnterpriseExamineeSubjectGradeScoreVo> subjectList;
            Map<String,BigDecimal> scoreMap = new HashMap<>();
            if (StringUtils.isEmpty(subjectId)) { // 总成绩表
                subjectList = enterpriseExamineeInfoMapper.getExamSubject(examId,null);

            }else{// 科目成绩表
                subjectList = enterpriseExamineeInfoMapper.getExamSubject(examId,subjectId);

            }

            if (CollectionUtils.isNotEmpty(subjectList)) {
                 fixedCellNum = fixedCellNum + subjectList.size();
                 for (ExportEnterpriseExamineeSubjectGradeScoreVo subjectVo : subjectList) {
                     if(CollectionUtils.isNotEmpty(subjectVo.getExportEnterpriseExamineeStemScoreVos())){
                         fixedCellNum = fixedCellNum + subjectVo.getExportEnterpriseExamineeStemScoreVos().size();
                     }
                 }
                if (lastCellIndex != fixedCellNum) {
                    throw new CustomException("导入文件列数与模板设定不一致，请检查!");
                }
                for (ExportEnterpriseExamineeSubjectGradeScoreVo subjectVo : subjectList) {
                    titles.add(subjectVo.getSubjectName());
                    keys.add("KM_"+subjectVo.getSubjectId());
                    scoreMap.put("KM_"+subjectVo.getSubjectId(),subjectVo.getSubjectScore());
                    if(CollectionUtils.isEmpty(subjectVo.getExportEnterpriseExamineeStemScoreVos())){
                        continue;
                    }
                    for (ExportEnterpriseExamineeStemScoreVo stemScoreVo :subjectVo.getExportEnterpriseExamineeStemScoreVos()){
                        titles.add(stemScoreVo.getStemName());
                        keys.add(subjectVo.getSubjectId()+"TG_"+stemScoreVo.getStemId());
                        scoreMap.put(subjectVo.getSubjectId()+"TG_"+stemScoreVo.getStemId(),stemScoreVo.getStemScore());
                    }
                }

            }

            for (int cIndex = firstCellIndex; cIndex < lastCellIndex; cIndex++) {   //遍历列
                Cell cell = headRow.getCell(cIndex);
                if (cell == null) {
                    continue;
                }
                if (!cell.toString().equals(titles.get(cIndex))) {
                    throw new CustomException("导入文件第" + (cIndex+1) + "列【" + cell.toString() + "】的列名或顺序与模板设定【" + titles.get(cIndex) + "】的列名不一致，请检查!");
                }

            }

            List<String> admissionNos = new ArrayList<>();
            int firstRowIndex = sheet.getFirstRowNum() + 1; // 第一行是列名，所以不读
            int lastRowIndex = sheet.getLastRowNum();
            for (int rIndex = firstRowIndex; rIndex <= lastRowIndex; rIndex++) { // 遍历行
                Row row = sheet.getRow(rIndex);
                if(ExcelUtil.isRowEmpty(row)){
                    continue;
                }
                String admissionNo =  ExcelUtil.getStringCellValue(row.getCell(0));
                if(admissionNos.contains(admissionNo)){
                    throw new CustomException("导入失败，模板数据第"+rIndex +"行,准考证号："+admissionNo+"重复，请检查！");
                }
                admissionNos.add(admissionNo);
                // 校验身份证号
                String idCard =  ExcelUtil.getStringCellValue(row.getCell(3));
                if (StringUtils.isEmpty(idCard) ||  idCard.length() > 50 ) {
                    throw new CustomException("导入失败，模板数据第"+rIndex +"行,考生证件号码 【" + idCard + "】超过50个字符长度，请检查！" );
                }

                Map<String,BigDecimal> cellValueStemMap = new HashMap<>(keys.size());
                Map<String,BigDecimal> cellValueSubjectMap = new HashMap<>(keys.size());

                for (int cIndex = 0; cIndex < keys.size(); cIndex++) { // 遍历列

                    if(StringUtils.isEmpty(ExcelUtil.getStringCellValue(row.getCell(cIndex)) )){
                        throw new CustomException("导入失败，模板数据第"+rIndex +"行,第"+cIndex+"列数据不为空，请检查！" );
                    }
                    if(cIndex >= 6){
                        if(!ExcelUtil.getStringCellValue(row.getCell(cIndex)).matches("\\d+(\\.\\d+)?")){
                            throw new CustomException("导入失败，模板数据第"+rIndex +"行,第"+cIndex+"列数据只能为数值，请检查！" );
                        }
                        if (keys.get(cIndex).indexOf("KM_") > -1) {
                            cellValueSubjectMap.put(keys.get(cIndex).replace("KM_",""),new BigDecimal(ExcelUtil.getStringCellValue(row.getCell(cIndex))));
                        } else if(keys.get(cIndex).indexOf("TG_") > -1){
                            cellValueStemMap.put(keys.get(cIndex),new BigDecimal(ExcelUtil.getStringCellValue(row.getCell(cIndex)) ));
                        }
                        if(null != scoreMap.get(keys.get(cIndex)) && scoreMap.get(keys.get(cIndex)).compareTo(new BigDecimal(ExcelUtil.getStringCellValue(row.getCell(cIndex)) )) < 0){
                            throw new CustomException("导入失败，模板数据第"+rIndex +"行,第"+cIndex+"列成绩大于设置的分数:"+scoreMap.get(keys.get(cIndex))+"，请检查！" );
                        }

                    }

                }
                for(Map.Entry<String,BigDecimal> entry : cellValueSubjectMap.entrySet()) {
                    BigDecimal subjectScore = entry.getValue();
                    BigDecimal stemScore = new BigDecimal("0");
                    for(Map.Entry<String,BigDecimal> stemEntry : cellValueStemMap.entrySet()) {
                        if(stemEntry.getKey().indexOf(entry.getKey()) > -1){
                            stemScore = stemScore .add(stemEntry.getValue());
                        }
                    }
                    if(MapUtils.isNotEmpty(cellValueStemMap) && null != subjectScore && subjectScore.compareTo(stemScore) != 0) {
                        throw new CustomException("导入失败，模板数据第"+rIndex +"行,科目成绩得分不等于题目得分总和，请检查！" );

                    }
                }
            }
            return readExcelFile(sheet, keys, examId, subjectId);

        } catch (Exception e) {
            log.error("导入成绩出现异常：",e);
            throw new CustomException("导入成绩出现异常：" + e.getMessage());
        } finally {
            IoUtil.close(fis);
            IoUtil.close(wb);
            long endTime = System.currentTimeMillis();
            log.info("导入成绩结束,共耗时{}秒",(endTime-startTime)/1000);
        }
    }

    /**
     * 读取Excel文件数据
     * @param sheet
     * @param keys 导入文件列标识
     * @param examId 考试ID
     * @param subjectId 科目ID
     * @return
     * @throws Exception
     */
    private Object[] readExcelFile(Sheet sheet, List<String> keys, String examId, String subjectId) throws Exception{
        List<EnterpriseExamineeInfoImportVo> list = new ArrayList<>(); // 成功数据
        List<EnterpriseExamineeInfoImportVo> errorlist = new ArrayList<>(); // 存放错误信息
        boolean flag = true; // 数据校验状态（false为存在错误）

        Map<String, EnterpriseExamineeInfoVo> existingExamineeGradeMap = getExistingExamineeGradeMap(examId); // 已存在的考生列表
        // 读取数据
        Map<String, Object> importExamineeGradeMap;
        int firstRowIndex = sheet.getFirstRowNum() + 1; // 第一行是列名，所以不读
        int lastRowIndex = sheet.getLastRowNum();
        Map<String, String> dataMap = dictDataService.selectDictDataMap("sys_user_sex", "V");
        Map<String, String> educationDataMap = dictDataService.selectDictDataMap("education", "V");
        dataMap.putAll(educationDataMap);
        //查询考试设置的科目分数线
        List<EnterpriseScoreLineSaveParam> scoreLineSettings = enterpriseExamScoreLineSettingService.getScoreLineList(examId, null,null);
         // 科目分数线
        Map<String, List<EnterpriseScoreLineSaveParam>> scoreLineMap = scoreLineSettings.stream().collect(Collectors.groupingBy(c -> c.getDimension()));
        List<EnterpriseScoreLineSaveParam> subjectScoreLineSettings  = scoreLineMap.get(CommonEnums.SCORE_LINE_DIMENSION_1.getCode());
        Map<String, List<ScoreLineItem>> subjectSngleScoreLineItemMap = enterpriseExamineeInfoService.getSngleScoreLineItemMap(subjectScoreLineSettings);
        List<ScoreLineItem> subjectRegionScoreLineItemList = enterpriseExamineeInfoService.getRegionScoreLineItems(subjectScoreLineSettings);

        //考试分数线
        List<EnterpriseScoreLineSaveParam> examScoreLineSettings  = scoreLineMap.get(CommonEnums.SCORE_LINE_DIMENSION_0.getCode());
        Map<String, List<ScoreLineItem>> examCompositeScoreLineItemMap = enterpriseExamineeInfoService.getCompositeScoreLineItemMap(examScoreLineSettings);
        Map<String, List<ScoreLineItem>> examSngleScoreLineItemMap = enterpriseExamineeInfoService.getSngleScoreLineItemMap(examScoreLineSettings);
        List<ScoreLineItem>  examRegionScoreLineItemList = enterpriseExamineeInfoService.getRegionScoreLineItems(examScoreLineSettings);
        for (int rIndex = firstRowIndex; rIndex <= lastRowIndex; rIndex++) { // 遍历行
            Row row = sheet.getRow(rIndex);
            if(row == null || ExcelUtil.isRowEmpty(row)){
                continue;
            }
            importExamineeGradeMap = new HashMap<>();
            for (int cIndex = 0; cIndex < keys.size(); cIndex++) { // 遍历列
                importExamineeGradeMap.put(keys.get(cIndex), ExcelUtil.getStringCellValue(row.getCell(cIndex)));
            }
            EnterpriseExamineeInfoImportVo examineeGradeVo = new EnterpriseExamineeInfoImportVo();
            setExamineeGrade(examineeGradeVo, keys, importExamineeGradeMap, existingExamineeGradeMap, dataMap, examId,
                    subjectId,subjectSngleScoreLineItemMap,subjectRegionScoreLineItemList);
            if (StringUtils.isNotEmpty(examineeGradeVo.getErrorMsg())) {
                flag = false;
                errorlist.add(examineeGradeVo);
                continue;
            }
            list.add(examineeGradeVo);

        }

        //设置考生合格逻辑
        Map<String,List<EnterpriseExamineeSubjectGradeVo>> subjectGradeMap = null;
        if(StringUtils.isNotEmpty(subjectId)){
            Set<String> examineeIds = list.stream().filter(e ->null != e.getEnterpriseExamineeInfo()).map(e ->e.getEnterpriseExamineeInfo().getId()).collect(Collectors.toSet());
            List<EnterpriseExamineeSubjectGradeVo> gradeVos =   enterpriseExamineeSubjectGradeMapper.selectEnterpriseExamineeSubjectByExamineeIds( examineeIds.toArray(new String[examineeIds.size()] ),examId);
            subjectGradeMap =  gradeVos.stream().collect(Collectors.groupingBy(c -> c.getExamineeId()));
        }
        for (EnterpriseExamineeInfoImportVo examineeGradeVo : list){
            if(StringUtils.isNotEmpty(subjectId)){
                if(MapUtils.isNotEmpty(subjectGradeMap) && CollectionUtils.isNotEmpty(subjectGradeMap.get(examineeGradeVo.getEnterpriseExamineeInfo().getId()))){
                    List<EnterpriseExamineeSubjectGrade> allGradeList = new ArrayList<>();
                    for(EnterpriseExamineeSubjectGradeVo gradeVo:subjectGradeMap.get(examineeGradeVo.getEnterpriseExamineeInfo().getId())){
                        EnterpriseExamineeSubjectGrade grade = new EnterpriseExamineeSubjectGrade();
                        BeanUtils.copyBeanProp(grade, gradeVo);
                        allGradeList.add(grade);
                    }
                    allGradeList.addAll(examineeGradeVo.getEnterpriseExamineeGradeList());
                    examineeGradeVo.getEnterpriseExamineeInfo().setQualifiedStatus(enterpriseExamineeInfoService.getExamQualifiedStatus(examSngleScoreLineItemMap
                            , examCompositeScoreLineItemMap, allGradeList ));
                    examineeGradeVo.getEnterpriseExamineeInfo().setRegionName(enterpriseExamineeInfoService.getExamRegionName(examRegionScoreLineItemList,allGradeList));
                }else{
                    examineeGradeVo.getEnterpriseExamineeInfo().setQualifiedStatus(enterpriseExamineeInfoService.getExamQualifiedStatus(examSngleScoreLineItemMap
                            , examCompositeScoreLineItemMap, examineeGradeVo.getEnterpriseExamineeGradeList()));
                    examineeGradeVo.getEnterpriseExamineeInfo().setRegionName(enterpriseExamineeInfoService.getExamRegionName(examRegionScoreLineItemList
                            ,examineeGradeVo.getEnterpriseExamineeGradeList()));
                }

            }else{
                examineeGradeVo.getEnterpriseExamineeInfo().setQualifiedStatus(enterpriseExamineeInfoService.getExamQualifiedStatus(examSngleScoreLineItemMap
                        , examCompositeScoreLineItemMap, examineeGradeVo.getEnterpriseExamineeGradeList()));
                examineeGradeVo.getEnterpriseExamineeInfo().setRegionName(enterpriseExamineeInfoService.getExamRegionName(examRegionScoreLineItemList
                        ,examineeGradeVo.getEnterpriseExamineeGradeList()));
//                getGroupQualifiedStatusAndRegionName(examineeGradeVo);
            }
        }


        // flag为false则返回errorlist
        if (!flag) {
            return new Object[]{flag, errorlist};
        }

        // list不为空则执行插入
        if (!org.springframework.util.CollectionUtils.isEmpty(list)) {
            batchInsertGrade(list,subjectId);
          }
        return new Object[]{flag, list.size()};
    }


    private  ExamInfo getExamInfo(String examId){
        //更新考试组其他考试考生数据
        //考试组(查询考试组设置的分数线，更新考试组的合格状态)
        ExamInfo examInfo = examInfoMapper.selectExamInfoById(examId);
        ExamInfo groupExamInfo =  examInfoMapper.selectExamInfoById(examInfo.getRelationId());
        return groupExamInfo;
    }

    private void getGroupQualifiedStatusAndRegionName( EnterpriseExamineeInfoImportVo examineeGradeVo){
        ExamInfo groupExamInfo =  getExamInfo (examineeGradeVo.getEnterpriseExamineeInfo().getExamId());
        //合并考试
        if(null != groupExamInfo && CommonEnums.EXAM_MERGE_TYPE_0.getCode().equals(String.valueOf(groupExamInfo.getMergeType()))){
            Map<String,String> tempMap = enterpriseGroupExamineeInfoService.getGroupQualifiedStatusAndRegionName(groupExamInfo.getId(),examineeGradeVo.getEnterpriseExamineeInfo().getIdcard(),examineeGradeVo.getEnterpriseExamineeInfo().getName());
            examineeGradeVo.getEnterpriseExamineeInfo().setGroupQualifiedStatus(tempMap.get("qualifiedStatus"));
            examineeGradeVo.getEnterpriseExamineeInfo().setGroupRegionName(tempMap.get("regionname"));
         }

    }


    private void dealGroupExamQualifiedStatusAndRegionName( List<EnterpriseExamineeInfoImportVo> examineeGradeVos){
        //更新考试组其他考试考生数据
        //考试组(查询考试组设置的分数线，更新考试组的合格状态)
        ExamInfo groupExamInfo =  getExamInfo (examineeGradeVos.get(0).getEnterpriseExamineeInfo().getExamId());
        //合并考试
        if(null == groupExamInfo || CommonEnums.EXAM_MERGE_TYPE_0.getCode().equals(String.valueOf(groupExamInfo.getMergeType()))){
            return;
        }
        for (EnterpriseExamineeInfoImportVo examineeGradeVo :examineeGradeVos) {
            Map<String,String> tempMap = enterpriseGroupExamineeInfoService.getGroupQualifiedStatusAndRegionName(groupExamInfo.getId(),examineeGradeVo.getEnterpriseExamineeInfo().getIdcard(),examineeGradeVo.getEnterpriseExamineeInfo().getName());
            examineeGradeVo.getEnterpriseExamineeInfo().setGroupQualifiedStatus(tempMap.get("qualifiedStatus"));
            examineeGradeVo.getEnterpriseExamineeInfo().setGroupRegionName(tempMap.get("regionname"));
            List<String> ids = Arrays.asList(tempMap.get("examineeIds").split(","));
//            Set<String> examineeIds = new HashSet<>(ids.size());
//            for (String id :ids){
//                if(id.equals(examineeGradeVo.getEnterpriseExamineeInfo().getId())){
//                    continue;
//                }
//                examineeIds.add(id);
//            }
            enterpriseExamineeInfoMapper.updateGroupQualifiedStatusAndRegionNameByIds(tempMap.get("qualifiedStatus"),tempMap.get("regionname"), ids.toArray(new String[ids.size()]));

        }
    }



    /**
     * 获取已存在的考生列表
     * @param examId 考试ID
     * @return
     */
    private Map<String, EnterpriseExamineeInfoVo> getExistingExamineeGradeMap(String examId ) {
        EnterpriseExamineeInfoVo enterpriseExamineeInfoVo = new EnterpriseExamineeInfoVo();
        enterpriseExamineeInfoVo.setExamId(examId);
         List<EnterpriseExamineeInfoVo> existingExamineeGradelist = enterpriseExamineeInfoMapper.selectEnterpriseExamineeGradeList(enterpriseExamineeInfoVo);
        if (!org.springframework.util.CollectionUtils.isEmpty(existingExamineeGradelist)) {
            return existingExamineeGradelist.stream().collect(Collectors.toMap(k -> k.getAdmissionNo(), EnterpriseExamineeInfoVo -> EnterpriseExamineeInfoVo));
        } else {
            return new HashMap<>();
        }
    }



    /**
     * 设置考生成绩数据
     * @param examineeGradeVo
     * @param keys 导入文件列标识
     * @param importExamineeGradeMap 导入文件行数据
     * @param existingExamineeGradeMap 已存在的考生成绩集合
     * @param dictMap 性别字典
     * @param examId 考试ID
     * @param subjectId 科目ID
     * @return
     * @throws Exception
     */
    private void setExamineeGrade(EnterpriseExamineeInfoImportVo examineeGradeVo, List<String> keys,  Map<String, Object> importExamineeGradeMap,
                                  Map<String,EnterpriseExamineeInfoVo> existingExamineeGradeMap, Map<String, String> dictMap, String examId,
                                  String subjectId,Map<String, List<ScoreLineItem>> subjectSngleScoreLineItemMap,
                                  List<ScoreLineItem> subjectRegionScoreLineItemList) throws Exception {
        User user = iBaseLoginService.getSysUser();
        String examineeId = IdUtils.generateId();
        EnterpriseExamineeInfo enterpriseExamineeInfo = new EnterpriseExamineeInfo();
        enterpriseExamineeInfo.setId(examineeId);
        enterpriseExamineeInfo.setExamId(examId);
        enterpriseExamineeInfo.setDeptId(iBaseLoginService.getDeptId());
        enterpriseExamineeInfo.setOfficeId(iBaseLoginService.getOfficeId());
        enterpriseExamineeInfo.setArchivedStatus(CommonEnums.ARCHIVED_STATUS_Y.getCode());
        enterpriseExamineeInfo.setOrigin(Integer.valueOf(CommonEnums.ORIGIN_0.getCode()));
        enterpriseExamineeInfo.createInfo(user.getLoginname());
        enterpriseExamineeInfo.updateInfo(user.getLoginname());
        List<EnterpriseExamineeSubjectGrade> enterpriseExamineeSubjectGradeList = new ArrayList<>();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            if (i < 6) {
                Field classField = EnterpriseExamineeInfo.class.getDeclaredField(key);
                classField.setAccessible(true);
                ImportAbstractService.setFieldValue(enterpriseExamineeInfo, importExamineeGradeMap.get(key), classField);
            } else {
                EnterpriseExamineeSubjectGrade grade = new EnterpriseExamineeSubjectGrade();
                grade.setId(IdUtils.generateId());
                grade.setExamId(examId);
                grade.setExamineeId(examineeId);
                if (key.indexOf("KM_") > -1) {
                    grade.setSubjectId(key.replace("KM_",""));
                    grade.setStemId("");
                } else if(key.indexOf("TG_") > -1){
                    if(StringUtils.isEmpty(subjectId)){
                        grade.setSubjectId(key.substring(0,key.indexOf("TG_")));
                        grade.setStemId(key.substring(key.indexOf("TG_")).replace("TG_",""));
                    }else{
                        grade.setSubjectId(subjectId);
                        grade.setStemId(key.substring(key.indexOf("TG_")).replace("TG_",""));
                    }

                }
                Object score = importExamineeGradeMap.get(key);
                if (null != score) {
                    grade.setScore(new BigDecimal(score.toString()));
                }
                grade.createInfo(SecurityUtils.getUsername());
                grade.updateInfo(SecurityUtils.getUsername());
                grade.setDeptId(iBaseLoginService.getDeptId());
                grade.setOfficeId(iBaseLoginService.getOfficeId());
                grade.setArchivedStatus("N");
                //设置科目合格
                grade.setQualifiedStatus(enterpriseExamineeInfoService.getGradeQualifiedStatus(grade,subjectSngleScoreLineItemMap));
                grade.setRegionName(enterpriseExamineeInfoService.getSubjectRegionName(subjectRegionScoreLineItemList,grade));
                enterpriseExamineeSubjectGradeList.add(grade);
            }
        }
        enterpriseExamineeInfo.setSex(dictMap.get(enterpriseExamineeInfo.getSex()));
        enterpriseExamineeInfo.setEducation(dictMap.get(enterpriseExamineeInfo.getEducation()));
        examineeGradeVo.setEnterpriseExamineeInfo(enterpriseExamineeInfo);
        examineeGradeVo.setEnterpriseExamineeGradeList(enterpriseExamineeSubjectGradeList);
        // 如果已存在考生成绩信息，则更新
        EnterpriseExamineeInfoVo examineeInfoVoOld = existingExamineeGradeMap.get(enterpriseExamineeInfo.getAdmissionNo());
        if (null != examineeInfoVoOld) {
            String examineeIdOld = examineeInfoVoOld.getId();
            enterpriseExamineeInfo.setId(examineeIdOld);
            enterpriseExamineeInfo.setArchivedStatus("N");
            enterpriseExamineeInfo.setCreateBy(null); // 更新不更新数据创建人
            enterpriseExamineeInfo.setCreateTime(null); // 更新不更新数据创建时间
            List<EnterpriseExamineeSubjectGradeVo> gradeVoListOld = existingExamineeGradeMap.get(enterpriseExamineeInfo.getAdmissionNo()).getGradeList();
            Map<String, EnterpriseExamineeSubjectGradeVo> gradeVoMapOld = gradeVoListOld.stream().collect(Collectors.toMap(k -> k.getSubjectId() + k.getStemId(), EnterpriseExamineeSubjectGradeVo -> EnterpriseExamineeSubjectGradeVo));
            for (EnterpriseExamineeSubjectGrade grade : enterpriseExamineeSubjectGradeList) {
                grade.setExamineeId(examineeIdOld);
                EnterpriseExamineeSubjectGradeVo gradeVoOld = gradeVoMapOld.get(grade.getSubjectId() + grade.getStemId());
                if (null == gradeVoOld) {
                   continue;
                }
                grade.setId(gradeVoOld.getId());
                grade.setExamineeId(examineeIdOld);
                grade.setCreateBy(null); // 更新不更新数据创建人
                grade.setCreateTime(null); // 更新不更新数据创建时间
            }
        }
    }

    /**
     * 字段设置名称
     * @param obj 设置的对象
     * @param val 设置的字段值
     * @param classField 设置的字段
     * @throws Exception
     */
//    private static void setFieldValue(Object obj, Object val, Field classField) throws Exception {
//        if (val != null) {
//            if (classField.getType() == Integer.class) {
//                classField.set(obj, Integer.parseInt(val.toString()));
//            } else if (classField.getType() == String.class) {
//                String value = val.toString().trim();
//                String arr[] = value.split("\\.");
//                if (arr.length > 1) {
//                    classField.set(obj, arr[0]);
//                } else {
//                    classField.set(obj, value);
//                }
//            } else if (classField.getType() == Long.class) {
//                classField.set(obj, Long.parseLong(val.toString()));
//            } else if (classField.getType() == BigDecimal.class) {
//                classField.set(obj, new BigDecimal(val.toString()));
//            }
//        }
//    }

    /**
     * 异步批量插入成绩
     * @param list
     */
    public void batchInsertGrade(List<EnterpriseExamineeInfoImportVo> list,String subjectId) {
        int count = list.size() % BATCH_COUNT == 0 ? list.size() / BATCH_COUNT : list.size() / BATCH_COUNT + 1;
        // 循环创建线程
        CountDownLatch countDownLatch = new CountDownLatch(count);
        List<FutureTask<Boolean>> resultList = Lists.newArrayList();
        for (int i = 0; i < count; i++) {
            List<EnterpriseExamineeInfoImportVo> gradeInfoVos = new ArrayList<>(BATCH_COUNT);
            if (i + 1 == count) {
                gradeInfoVos.addAll(list.subList(i * BATCH_COUNT, list.size()));
            } else {
                gradeInfoVos.addAll(list.subList(i * BATCH_COUNT, (i + 1) * BATCH_COUNT));
            }
            FutureTask<Boolean> future =  new FutureTask<>(new EnterpriseExamineeGradeImportServiceImpl.ImportGradeTask(gradeInfoVos, countDownLatch,subjectId));
            threadPoolTaskExecutor.submit(future);
            //将任务执行结果存储到List中
            resultList.add(future);

        }
        try {
            countDownLatch.await();
            for (FutureTask<Boolean> futureTask : resultList) {
                if(!futureTask.get()){
                    throw new CustomException(BizErrorCode.GRADE_E0006);
                }
            }
            log.info("异步批量插入成绩任务完成" + DateUtils.localDateMillisToString(LocalDateTime.now()));
        } catch (InterruptedException e) {
            log.error(e.getCause().getMessage());
            Thread.currentThread().interrupt();
            throw new CustomException(BizErrorCode.GRADE_E0006);
        } catch (ExecutionException e) {
            // 看看失败原因
            log.error(e.getCause().getMessage());
            throw new CustomException(BizErrorCode.GRADE_E0006);
        }
    }

    /**
     * 异步插入成绩处理
     */
    public class ImportGradeTask  implements Callable<Boolean> {

        private List<EnterpriseExamineeInfoImportVo> gradeInfoVos;

        private CountDownLatch countDownLatch;

        private String subjectId;

        public ImportGradeTask(List<EnterpriseExamineeInfoImportVo> gradeInfoVos,CountDownLatch countDownLatch,String subjectId) {
            this.gradeInfoVos = gradeInfoVos;
            this.countDownLatch = countDownLatch ;
            this.subjectId = subjectId;
        }

        @Override
        public Boolean call(){
            try {
                log.info("SaveData size: {}", gradeInfoVos.size());
                enterpriseExamineeInfoService.insertBatchEnterpriseExamineeGrade(gradeInfoVos);
//                if(StringUtils.isNotEmpty(subjectId)){
//                    dealGroupExamQualifiedStatusAndRegionName(gradeInfoVos);
//                }

                return true;
            } finally {
                countDownLatch.countDown();
            }
        }
    }

}
